package server

import (
	"fmt"
	"github.com/panjf2000/gnet/v2"
	"go.uber.org/atomic"
	"time"
	"wths/wthsjy-im/server/handle"
	"wths/wthsjy-im/server/topic"
)

const (
	kcpKeyPassword = "___自定义密码____"
	kcpKeySalt     = "___自定义盐_____"
	kcpSndwnd      = 4 * 1024
	kcpRcvwnd      = 4 * 1024
	readBuffer     = 4 * 1024 * 1024
	writeBuffer    = 4 * 1024 * 1024
)

type SvrConfig struct {
	WithKCP       bool
	HandlerFunc   handle.MessageHandle
	GNetMulticore bool
	Port          string
}

type ImServer struct {
	gnet.BuiltinEventEngine
	eng      gnet.Engine
	topicMgr *topic.TopicsManager
	connNum  atomic.Int32
	conf     *SvrConfig
}

func NewImServer(conf *SvrConfig) *ImServer {
	if conf.HandlerFunc == nil {
		panic("handlerFunc is nil")
	}

	svr := &ImServer{
		topicMgr: topic.NewTopicsManager(),
		conf:     conf,
	}
	return svr
}

func (ims *ImServer) Run() {
	// tcp/websocket with gnet
	go func() {
		err := ims.runGNet()
		if err != nil {
			panic(err)
		}
	}()

	// kcp
	if ims.conf.WithKCP {
		err := ims.runKCP()
		if err != nil {
			panic(err)
		}
	}
}

// runGNet tcp/websocket
func (ims *ImServer) runGNet() error {
	return gnet.Run(ims, fmt.Sprintf("tcp://%s", ims.conf.Port),
		gnet.WithMulticore(ims.conf.GNetMulticore),
		gnet.WithReusePort(true),
		gnet.WithTicker(true),
		gnet.WithTCPNoDelay(gnet.TCPNoDelay),
		gnet.WithSocketRecvBuffer(readBuffer),
		gnet.WithSocketSendBuffer(writeBuffer),
	)
}

func (ims *ImServer) Monitor() {
	for {
		time.Sleep(time.Second * 10)
		ims.topicMgr.PushMessageToTopic("topic111", []byte(time.Now().String()))
	}
}
